home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 March / Macworld (1998-03) (Disk 1).dmg / Shareware World / Utilities / Text Processing / Alpha / Tcl / Completions / TeXCompletions.tcl < prev   
Encoding:
Text File  |  1997-12-18  |  20.4 KB  |  670 lines  |  [TEXT/ALFA]

  1. ## -*-Tcl-*-
  2.  # ###################################################################
  3.  #    Vince's    Additions -    an extension package for Alpha
  4.  # 
  5.  #    FILE: "TeXCompletions.tcl"
  6.  #                                      created: 26/2/96 {2:27:17 pm} 
  7.  #                                  last update: 18/12/97 {8:28:19 am} 
  8.  #    Author:    Vince Darley
  9.  #    E-mail:    <darley@fas.harvard.edu>
  10.  #      mail:    Division of    Applied    Sciences, Harvard University
  11.  #            Oxford Street, Cambridge MA    02138, USA
  12.  #       www:    <http://www.fas.harvard.edu/~darley/>
  13.  #    
  14.  #    Adds completion routines for TeX mode.  This includes reference
  15.  #    (\label) completion, citation completion, environment completion,
  16.  #    environment item insertion.  
  17.  #    
  18.  #    Also adds electric routines, and 'option-click-titlebar' code,
  19.  #    better cmd-dlb-click procedure, better marking for .sty files,
  20.  #    and much more...
  21.  #    
  22.  #    Cool new feature: the '{' key is bound to electric completion.
  23.  #    This means you can just type as normal in most circumstances,
  24.  #    and when you hit '{', if the previous text is capable of being
  25.  #    extended as a command (e.g. \begin, \frac, ...), then it is!
  26.  # 
  27.  #  modified by  rev reason
  28.  #  -------- --- --- -----------
  29.  #  18/12/97 VMD 1.1 added TeX::IncludeFile completions, better handling of '*'
  30.  # ###################################################################
  31.  ##
  32.  
  33. # ◊◊◊◊ completions & expanders ◊◊◊◊ #
  34. ensureset completions(TeX) {beginContraction Env Cmd Electric Reference Cite Word}
  35. ensureset expanders(TeX) {ExCmd}
  36.  
  37. # ◊◊◊◊ Preferences ◊◊◊◊ #
  38.  
  39. # Add an item inside any environment 
  40. # bound to shift-opt-i
  41. newPref binding TeXAddItem "/I<U<I" TeX "" 1
  42. # you can turn off the electric left brace with this:
  43. newPref flag elecLBrace 1 TeX
  44.  
  45.  
  46. newPref f showTitlesWithTeXCiteCompletion 1 TeX
  47. newPref v standardTeXLabelDelimiter ":" TeX TeX::labelDelimChanged
  48. # complete an environment even if we don't recognise it!
  49. newPref f acceptAnyTeXEnvironment 1 TeX
  50. # if we don't recognise the environment, create a body on the fly
  51. newPref f promptToCreateTeXEnvironment 1 TeX
  52. newPref f electricContractions 1 TeX
  53.  
  54. # ◊◊◊◊ extra invoker key ◊◊◊◊ #
  55.  
  56. proc TeX::electricLeft {} {
  57.     global TeXmodeVars
  58.     set p [getPos]
  59.     if {$TeXmodeVars(electricContractions)} {
  60.         catch {TeX::Completion::beginContraction}
  61.     }
  62.     if {[getPos] == $p} {
  63.         catch {TeX::Completion::Electric}
  64.     }
  65.     if {[getPos] == $p} {typeText "\{"}
  66. }
  67.  
  68. # ◊◊◊◊ Completions ◊◊◊◊ #
  69.  
  70. ## 
  71.  # -------------------------------------------------------------------------
  72.  # 
  73.  # "TeX::Completion::beginContraction" --
  74.  # 
  75.  #  The idea here is to see if you see a hint in the form of 
  76.  #  "b'<some-word>", if so replace the "b'" with "\begin ".
  77.  # -------------------------------------------------------------------------
  78.  ##
  79. proc TeX::Completion::beginContraction {{dummy ""}} {
  80.     set lastword [completion::lastTwoWords leadingHint]
  81.     if {$leadingHint != "b'"} {return 0} 
  82.     set curPos [getPos]
  83.     backwardWord
  84.     set startEnvPos [getPos]
  85.     set evironmentHint [getText $startEnvPos $curPos]
  86.     backwardWord
  87.     deleteText [getPos] $curPos
  88.     insertText "\\begin"
  89.     TeX::Completion::Electric "begin"
  90.     typeText $lastword
  91.     return 0
  92. }
  93.  
  94. ## 
  95.  # -------------------------------------------------------------------------
  96.  #     
  97.  # "TeX::Completion::Env" --
  98.  #    
  99.  #    Complete the contents of a \begin...\end pair as appropriate.  Uses    the
  100.  #    TeXbodies array.  You can either type '\begin<cmd-Tab>figure<cmd-Tab>'
  101.  #    (for example) or just '\begin{figure}<cmd-Tab>'.
  102.  # -------------------------------------------------------------------------
  103.  ##
  104. proc TeX::Completion::Env {dummy} {
  105.     set cmd [completion::lastTwoWords begin]
  106.     if { $begin != "\\begin\{" } { return 0 }
  107.     if [regexp {^(.*)\}$} $cmd dmy cmd] {
  108.         # hmm
  109.     }
  110.     set matches [completion::modeList $cmd TeXenvironments]
  111.     if { $matches == 0 } {
  112.         global TeXmodeVars TeXbodies
  113.         if [info exists TeXbodies($cmd)] {
  114.             set match $cmd
  115.         } else {            
  116.             if {$TeXmodeVars(acceptAnyTeXEnvironment)} {
  117.                 if $TeXmodeVars(promptToCreateTeXEnvironment) {
  118.                     set y 40
  119.                     set yb 200
  120.                     set res [eval dialog -w 400 -h 340 \
  121.                     [dialog::title "New TeX environment" 400] \
  122.                     [dialog::button "OK" 310 yb] \
  123.                     [dialog::button "Cancel" 310 yb] \
  124.                     [dialog::text "Enter the template for the body of the environment" 10 y] \
  125.                     [dialog::text "Write '•prompt message•' for each template stop," 10 y] \
  126.                     [dialog::text "'\\r','\\\{','\\t',... for return, brace, tab etc." 10 y] \
  127.                     [dialog::edit "•body•" 10 y 35 6] \
  128.                     ]
  129.                     set match $cmd
  130.                     if {![lindex $res 1]} {
  131.                         eval set "TeXbodies($match)" [lindex $res 2]
  132.                         addUserLine "set TeXbodies($match) \"[quoteExpr3 $TeXbodies($match)]\""
  133.                     } else {
  134.                         # we cancelled, so move on
  135.                         completion::already error
  136.                         return 1
  137.                     }
  138.                 } else {
  139.                     message "Warning: I don't recognise that environment"
  140.                     set match $cmd
  141.                 }
  142.             } else {
  143.                 return 0
  144.             }
  145.         }
  146.     } else {
  147.         set match [completion::Find $cmd $matches]
  148.     }    
  149.     if [string length $match] {
  150.         # we completed or cancelled, so move on
  151.         completion::already error
  152.         if { $match == 1 } {
  153.             return 1
  154.         } else {
  155.             if {![ring::type]} {
  156.                 global TeXbodyOptions
  157.                 if [info exists TeXbodyOptions($match)] {
  158.                     endOfLine
  159.                     elec::Insertion $TeXbodyOptions($match)
  160.                 }
  161.                 ring::+
  162.                 set p [getPos]
  163.                 ring::+
  164.                 insertText $match
  165.                 goto $p
  166.                 return [elec::findCmd $match TeXbodies ""]
  167.             }
  168.             if {![ring::TMarkAt "environment name" [expr [getPos] - [string length $match]]]} {
  169.                 # we probably typed '\begin{name}' all in one go
  170.                 set i "••"
  171.                 if {[lookAt [expr [getPos]-1]] != "\}"} {
  172.                     append i "\}"
  173.                 }
  174.                 global TeXbodyOptions
  175.                 if [info exists TeXbodyOptions($match)] {
  176.                     append i $TeXbodyOptions($match)
  177.                 }
  178.                 append i "\r\t••\r\\end\{${match}\}\r••"
  179.                 elec::Insertion $i
  180.                 ring::+
  181.             } else {
  182.                 global TeXbodyOptions
  183.                 if [info exists TeXbodyOptions($match)] {
  184.                     endOfLine
  185.                     elec::Insertion $TeXbodyOptions($match)
  186.                 }
  187.                 ring::+
  188.                 set p [getPos]
  189.                 # delete the stop of the body
  190.                 ring::deleteStopAndMove
  191.                 # delete the stop of the \end{•}
  192.                 ring::deleteStop
  193.                 # we need to fill in the '\end{}'
  194.                 insertText $match
  195.                 goto $p
  196.             }
  197.             set ret [elec::findCmd $match TeXbodies ""]
  198.             # delete the stop of \begin{•}
  199.             # we do this afterwards, otherwise we lose the nesting of
  200.             # templates, which is bad.
  201.             ring::-
  202.             ring::deleteStopAndMove
  203.             return $ret
  204.         }
  205.     } else {
  206.         completion::already TeX::Completion::Env
  207.         return 1
  208.     }    
  209. }
  210.  
  211. ## 
  212.  # -------------------------------------------------------------------------
  213.  #     
  214.  # "TeX::Completion::Cmd" --
  215.  #    
  216.  #    Takes account of the backslash which commands in TeX use
  217.  # -------------------------------------------------------------------------
  218.  ##
  219. proc TeX::Completion::Cmd {dummy} {
  220.     set cmd [completion::lastWord pos]
  221.     if {[regexp {^\\([^\*]*)\*?$} $cmd "" cmd]} {
  222.         return [completion::cmd [string range $cmd 1 end]]
  223.     } else {
  224.         return 0
  225.     }
  226. }
  227.  
  228. ## 
  229.  # -------------------------------------------------------------------------
  230.  #     
  231.  #    "TeX::Completion::Electric"    --
  232.  #    
  233.  #     An    example    of calling the completion::electric procedure. 
  234.  #     In TeX mode, '{••}••' is a good default.
  235.  # -------------------------------------------------------------------------
  236.  ##
  237. proc TeX::Completion::Electric { {cmd ""} } {
  238.     if ![string length $cmd] { 
  239.         if [containsSpace $cmd] { return 0 }
  240.         set cmd [completion::lastWord]
  241.     }
  242.     if {[regexp {^\\([^\*]*)\*?$} $cmd "" cmd]} {
  243.         # nothing
  244.     } elseif {[regexp {\]\{?$} $cmd got]} {
  245.         # we might have an optional [...] after the command we really want.
  246.         # This should work but doesn't (Alpha bug)!
  247.         #{matchIt "]" [pos::math [getPos] - [expr 1 + [string length $got]]]}
  248.         if ![catch {search -s -f 0 -r 0 -m 0 "\[" [getPos]} where] {
  249.             set p [getPos]
  250.             goto [lindex $where 0]
  251.             set cmd [completion::lastWord]
  252.             goto $p
  253.             regexp {^\\([^\*]*)\*?$} $cmd "" cmd
  254.         }
  255.     }
  256.     return [completion::electric $cmd "\{••\}••"]
  257. }
  258.  
  259.     
  260. ## 
  261.  # -------------------------------------------------------------------------
  262.  #     
  263.  # "TeX::Completion::Reference"    --
  264.  #    
  265.  #    If we're in    any    kind of    reference, search for appropriate labels to
  266.  #    get    the    information    from and fill them in.    'TeXRefCompletion'
  267.  #    in "latexEngine.tcl" is    obsolete.
  268.  # -------------------------------------------------------------------------
  269.  ##
  270. proc TeX::Completion::Reference { {dummy ""} } {
  271.     global __wc__insPos completion_got completion_looking
  272.     global _texrefprefixes
  273.     # cursor changed place?
  274.     set pos [getPos]
  275.     if $pos==$__wc__insPos {
  276.         completion::update TeX::Completion::Reference $completion_got $completion_looking
  277.         message "press <Cmd Tab> for another label"
  278.         return 1
  279.     }
  280.  
  281.     global TeXmodeVars
  282.  
  283.     set lastword [completion::lastTwoWords prevword]
  284.     set gotprefix ""
  285.     set prevword [string trim [string range $prevword 1 end] "\{"]
  286.     if {[set ref [lsearch -exact $TeXmodeVars(refCommands) $prevword]] != -1} {
  287.         set gotprefix $lastword
  288.         set lastword $prevword
  289.     } else {
  290.         # trim the backslash and opening brace:
  291.         set lastword [string trim [string range $lastword 1 end] "\{"]
  292.         # check if it's a \ref-like command:
  293.         set ref [lsearch -exact $TeXmodeVars(refCommands) $lastword]
  294.     }    
  295.     
  296.     if { $ref != -1 } {
  297.         # got a \ref-like command:
  298.         set completion_got "\\[lindex $TeXmodeVars(refCommands) $ref]\{${gotprefix}"
  299.         # make sure we have the brace:
  300.         if { $gotprefix == "" && [lookAt [expr $pos -1]] != "\{" } {
  301.             insertText "\{"
  302.         }
  303.         set completion_looking "label\{${gotprefix}"
  304.         TeX::updateCompletion TeX::Completion::Reference $completion_got $completion_looking
  305.         completion::already TeX::Completion::Reference
  306.         return 1
  307.     } else {
  308.         completion::already TeX::Completion::Reference
  309.         return 0 
  310.     }
  311. }
  312.  
  313. ## 
  314.  # -------------------------------------------------------------------------
  315.  #     
  316.  # "TeX::Completion::Cite" --
  317.  #    
  318.  #    Checks for any \cite like command, and looks up    the    partial    argument
  319.  #    in the known bibliographies, completing    the    entry as appropriate.
  320.  # -------------------------------------------------------------------------
  321.  ##
  322. proc TeX::Completion::Cite { {dummy ""} } {
  323.     global __wc__insPos completion_got completion_looking TeXmodeVars
  324.     # cursor changed place?
  325.     if [getPos]==$__wc__insPos {
  326.         set lastword [completion::lastWord]
  327.         set completion_got [completion::modeList $lastword completion_got]
  328.     } else {
  329.         global TeXmodeVars
  330.         set a [getText [lineStart [getPos]] [getPos]]
  331.         # got a \cite-like command:
  332.         if ![regexp "\\\\([join [string trim $TeXmodeVars(citeCommands)] |])\\\{(\[a-zA-Z0-9\]+,)*(\[a-zA-Z0-9\]+)$" $a d d d lastword] {
  333.             return 0
  334.         }
  335.         set completion_got [bib_FindAllEntries $lastword $TeXmodeVars(showTitlesWithTeXCiteCompletion)]
  336.         if {$completion_got == ""} {
  337.             if {[askyesno "No matching citations found.  Perhaps you should rebuild your bib data-base.  Do you want to do this now?"] == "yes"} {
  338.                 if $TeXmodeVars(showTitlesWithTeXCiteCompletion) {
  339.                     bibMakeDatabase
  340.                 } else {
  341.                     bibMakeIndex
  342.                 }
  343.                 # try again
  344.                 return [TeX::Completion::Cite $dummy]
  345.             }
  346.             return 0
  347.         } else {
  348.             set completion_got " ${completion_got} "
  349.         }
  350.     }
  351.     if $TeXmodeVars(showTitlesWithTeXCiteCompletion) {
  352.         set query "Rebuild Bibliography Database"
  353.         set rebuild bibMakeDatabase
  354.     } else {
  355.         set query "Rebuild Bibliography Index"
  356.         set rebuild bibMakeIndex
  357.     }
  358.     set match [completion::Find $lastword $completion_got \
  359.         $TeXmodeVars(showTitlesWithTeXCiteCompletion) 1 $query $rebuild]
  360.     if {$match != ""} {
  361.         if {[lookAt [getPos]] != "\}"} { insertText "\}" }
  362.     }
  363.     # we never bother with calling ourselves again, since we forced the above
  364.     # 'completion::Find' call to complete.
  365.     completion::already error
  366.     return 1
  367. }
  368.  
  369. proc TeX::Completion::Word {dummy} {
  370.     # we only complete the word if it doesn't end in some command
  371.     if { [lookAt [expr [getPos] -1]] != "\{" } {
  372.         return [completion::word $dummy]
  373.     }
  374. }
  375.  
  376. # ◊◊◊◊ helpers ◊◊◊◊ #
  377.  
  378. proc TeX::updateCompletion { proc {got ""} {looking ""} } {
  379.     if [completion::general $got $looking] {
  380.         completion::already $proc
  381.         if {[lookAt [getPos]] != "\}"} {
  382.             insertText "\}"
  383.         } 
  384.         message "press <Cmd Tab> for another label"
  385.         return 1
  386.     } else {
  387.         completion::already error
  388. #         if {[lookAt [expr [getPos] - 1]] != "\}"} {
  389. #             elec::Insertion "\}••"        
  390. #         } 
  391.         error ""
  392.         return 0
  393.     }
  394. }    
  395.  
  396. # ◊◊◊◊ experimental ◊◊◊◊ #
  397.  
  398. ## 
  399.  # -------------------------------------------------------------------------
  400.  # 
  401.  # "TeX::ForceCompletion::Cmd" --
  402.  # 
  403.  #  As far as I can see, this is not currently called anywhere. Perhaps it 
  404.  #  is an abandoned experiment? -trf
  405.  #  
  406.  #  At one point is was useful, but currently not called as you say -vince
  407.  # -------------------------------------------------------------------------
  408.  ##
  409. proc TeX::Completion::ForceCmd {{dummy ""}} {
  410.     global __g_cmd_start __g_last_match    __g_last_match_pos __g_cmd_length TeXcmds
  411.     set    pos    [getPos]
  412.     set    cmd    [completion::lastWord cmd_start]
  413.     # if there's any whitespace    in the command then    it's no    good to    us
  414.     if [string match " \t" $cmd] { message "No command to complete"; return    0 }
  415.     if { $cmd_start    == $__g_cmd_start }    {
  416.         # it's an old match    so we want the next
  417.         if { [set found    [lsearch [lrange $TeXcmds $__g_last_match_pos end] "\\${cmd}*" ]] == -1    } {
  418.             message    "No    more commands"
  419.             select $__g_cmd_start [expr    $__g_cmd_start + [string length    $__g_last_match]]]
  420.             return 1
  421.         } else {
  422.             set    oldLength [string length $__g_last_match]
  423.             incr __g_last_match_pos    $found
  424.             set    __g_last_match [lindex $TeXcmds    $__g_last_match_pos]
  425.             set    completion [string range $__g_last_match $__g_cmd_length end]
  426.             replaceText    [expr $__g_cmd_start + $__g_cmd_length]    \
  427.                 [expr $__g_cmd_start + $oldLength] \
  428.                 $completion
  429.         }
  430.     } else {
  431.         # it's a new match
  432.         if { [set __g_last_match_pos [lsearch $TeXcmds "\\${cmd}*" ]] == -1    } {
  433.             message    "No    such command"; return 0
  434.         } else {
  435.             set    __g_cmd_start $cmd_start
  436.             set    __g_last_match [lindex $TeXcmds    $__g_last_match_pos]
  437.             set    __g_cmd_length [string length $cmd]
  438.             incr __g_cmd_length    -1
  439.             set    completion [string range $__g_last_match $__g_cmd_length end]
  440.             insertText $completion
  441.         }
  442.     }
  443.     return 1
  444. }
  445.  
  446. # ◊◊◊◊ setup various arrays for electrics ◊◊◊◊ #
  447. uplevel \#0 [list source ${HOME}:Tcl:Completions:TeXcmds.tcl]
  448.  
  449. proc TeX::labelDelimChanged {args} {
  450. uplevel \#0 {
  451. set _x $TeXmodeVars(standardTeXLabelDelimiter)
  452. set TeXelectrics(*section) "\{•section name•\}\n••"
  453. set TeXelectrics(frac) "\{•numerator•\}\{•denominator•\}••"
  454. set TeXelectrics(sum) "_\{•from•\}^\{•to•\}••"
  455. set TeXelectrics(emph) "◊1"
  456. set TeXelectrics(includegraphics) "◊\[TeX::IncludeFile\]"
  457. set TeXelectrics(begin) "\{•environment name•\}\n\t•body•\n\\end\{••\}\n••"
  458. set TeXelectrics(Sec*) "◊kill0Section~\\ref\{sec${_x}•label•\}••"
  459. set TeXelectrics(Table) "~\\ref\{tab${_x}•label•\}••"
  460. set TeXelectrics(App*) "◊kill0Appendix~\\ref\{sec${_x}•label•\}••"
  461. set TeXelectrics(Eq.) "~\\eqref\{eq${_x}•label•\}••"
  462. set TeXelectrics(Fig*) "◊kill0Figure~\\ref\{fig${_x}•label•\}••"
  463. set TeXelectrics(Cha*) "◊kill0Chapter~\\ref\{chap${_x}•label•\}••"
  464. #set TeXelectrics(subfigure) "\[•caption•\]\{\\label\{fig${_x}••\}\}\%\r\\includegraphics\[•width=,height=•\]\{•eps file•\}\}"
  465. set TeXbodies(equation) "•equation body•\n\\label\{eq${_x}•label•\}"
  466. set TeXbodies(description) "\\item\[•name•\] •description•\n\n\\item\[•name•\] •description•\n"
  467. set TeXbodies(enumerate) "\\item ••\n\n\\item ••\n"
  468. set TeXbodies(itemize) "\\item ••\n\n\\item ••\n"
  469. set TeXbodies(figure) "◊\[TeX::Figure\]"
  470. set TeXbodies(align) "•equation 1 l.h.s.• &•• \n\\label\{eq${_x}••\} \\\\\n•equation 2 l.h.s.• &•• \n\\label\{eq${_x}••\}"
  471. set TeXbodies(gather) "•• \n\\label\{eq${_x}••\} \\\\\n•• \n\\label\{eq${_x}••\}"
  472. set TeXbodies(split) "•• &•• \\\\\n•• &•• \\\\"
  473. set TeXbodies(cases) "•• & •• \\\\\n•• & ••"
  474. # currently these 'bodyOptions' cannot contain bullets
  475. set TeXbodyOptions(enumerate) "\[a|i\]"
  476. set TeXbodyOptions(figure) "\[tbp\]"
  477. set TeXbodyOptions(floatingfigure) "\{2in\}"
  478. set TeXEnvItems(enumerate) "\n\\item ••"
  479. set TeXEnvItems(itemize) "\n\\item ••"
  480. set TeXEnvItems(description) "\n\\item\[•name•\] •description•"
  481. set TeXEnvItems(align) "\\\\\n•next equation l.h.s.• &•• \n\\label\{eq${_x}••\} "
  482. set TeXEnvItems(gather) "\\\\\n•• \n\\label\{eq${_x}••\} "
  483. set TeXEnvItems(split) "•• &•• \\\\"
  484. set TeXEnvItems(cases) "•• &•• \\\\"
  485. set _texrefprefixes [list fig${_x} eq${_x} sec${_x} chap${_x} tab${_x} ]
  486. unset _x
  487. }
  488.  
  489. }
  490.  
  491. # call it now
  492. TeX::labelDelimChanged
  493.  
  494. # ◊◊◊◊ label returners ◊◊◊◊ #
  495.  
  496. proc TeX::labelDelim {} {
  497.     global TeXmodeVars
  498.     return $TeXmodeVars(standardTeXLabelDelimiter)
  499. }
  500. proc TeX::label {type} {
  501.     global TeXmodeVars
  502.     return "\\label\{${type}$TeXmodeVars(standardTeXLabelDelimiter)••\}"
  503. }
  504.  
  505. # ◊◊◊◊ environment assistors ◊◊◊◊ #
  506.  
  507. ## 
  508.  # -------------------------------------------------------------------------
  509.  #     
  510.  # "TeXAddItem"    --
  511.  #    
  512.  #    Scan the local environment and insert a    new    item into that environment,
  513.  #    of the appropriate type.
  514.  #    
  515.  #    Currently not too sophisticated.
  516.  # -------------------------------------------------------------------------
  517.  ##
  518. proc TeXAddItem {} {
  519.     set env [lindex [split [eval getText [searchEnvironment]] "{}"] 1]
  520.     global TeXEnvItems
  521.     if ![catch {set item $TeXEnvItems($env)}] {
  522.         elec::Insertion $item
  523.     }
  524. }
  525.  
  526. # ◊◊◊◊ Template embeddable proc's ◊◊◊◊ #
  527.  
  528. proc TeX::IncludeFile {} {
  529.     # could try to ensure this file's on the search path?
  530.     if ![regexp {\{, } [lookAt [pos::math [getPos] - 1]]] {
  531.         append res "\{"
  532.     }
  533.     append res [file tail [getfile "Name of file to include:"]]
  534.     return $res
  535. }
  536.  
  537. proc TeX::Figure {} {
  538.     set fig_types [list "Normal" "Floating" \
  539.         "2 side-by-side" "3 side-by-side" "4 side-by-side" \
  540.         "2, one above the other" \
  541.         "4 in a 2x2 block" \
  542.         "6 with 3 across, 2 down" \
  543.         "6 with 2 across, 3 down" \
  544.         "other…" \
  545.         ]
  546.     set fig [listpick -p "Pick a figure type to insert:" $fig_types]
  547.     if {$fig == ""} { return "" }
  548.     set t ""
  549.     switch $fig {
  550.         "Normal" -
  551.         "Floating" {
  552.             append t "\\centerline\{\\includegraphics\[•shape,orientation•\]"
  553.             append t "\{•graphics file•\}\}\r"
  554.             append t "\\caption•\[short title for t.o.f.\]•\{•caption•\}\r"
  555.             append t "\\protect[TeX::label fig]"
  556.             if {$fig == "Floating"} {
  557.                 text::replace {\begin{figure}} {\begin{floatingfigure}} 0
  558.                 text::replace {\end{figure}} {\end{floatingfigure}} 1
  559.                 TeX::RequirePackage floatflt
  560.             }
  561.         }
  562.         "2 side-by-side" {
  563.             append t [TeX::_subFigure 2 1]
  564.         }
  565.         "3 side-by-side" {
  566.             append t [TeX::_subFigure 3 1]
  567.         }
  568.         "4 side-by-side" {
  569.             append t [TeX::_subFigure 4 1]
  570.         }
  571.         "2, one above the other" {
  572.             append t [TeX::_subFigure 1 2]
  573.         }
  574.         "4 in a 2x2 block" {
  575.             append t [TeX::_subFigure 2 2]
  576.         }
  577.         "6 with 3 across, 2 down" {
  578.             append t [TeX::_subFigure 3 2]
  579.         }
  580.         "6 with 2 across, 3 down" {
  581.             append t [TeX::_subFigure 2 3]
  582.         }
  583.         "other…" {
  584.             set w [prompt "Number of subfigures, horizontally" "2"]
  585.             set h [prompt "Number of subfigures, vertically" "2"]
  586.             append t [TeX::_subFigure $w $h]
  587.         }
  588.         
  589.     }
  590.     return $t    
  591. }
  592.  
  593. # ◊◊◊◊ embeddable proc helpers ◊◊◊◊ #
  594.  
  595. ## 
  596.  # -------------------------------------------------------------------------
  597.  # 
  598.  # "TeX::_subFigure" --
  599.  # 
  600.  #  This is a helper, it is only called form the above proc.
  601.  # -------------------------------------------------------------------------
  602.  ##
  603. proc TeX::_subFigure {w h} {
  604.     TeX::RequirePackage subfigure
  605.     set t "\\centering\r"
  606.     set wnum [lindex {x "" two three four five six seven} $w]
  607.     for {set hh $h} {$hh >0} {incr hh -1} {
  608.         for {set ww $w} {$ww >0} {incr ww -1} {
  609.             append t "\\subfigure\[•subfig caption•\]\{[TeX::label fig]%\r"
  610.             append t "\t\\includegraphics\[width=\\figs${wnum}\]"
  611.             append t "\{•graphics file•\}\}"
  612.             if {$ww != 1} {
  613.                 append t "\\goodgap${wnum}\r"
  614.             } else {
  615.                 if {$hh != 1} {
  616.                     append t "\\\\\r"
  617.                 } else {
  618.                     append t "%\r"
  619.                 }
  620.             }
  621.         }
  622.     }
  623.     append t "\\caption•\[short caption for t.o.f.\]•\{•caption•\}\r"
  624.     append t "[TeX::label fig]"
  625. }
  626.  
  627. # ◊◊◊◊ Expansions ◊◊◊◊ #
  628. namespace eval TeX::Expansion {}
  629.  
  630. proc TeX::Expansion::ExCmd { {cmd ""} {dictExt "acronyms"}} {
  631.     if ![string length $cmd] { 
  632.         set cmd [completion::lastWord]
  633.         # if there's any whitespace in the command then it's no good to us
  634.         if [containsSpace $cmd] { return 0 }
  635.     }
  636.  
  637.     set m [modeALike]
  638.     set hint [string trim [join [split $cmd \\ ]]]
  639.     
  640.     if { [set matches [elec::acronymListExpansions $hint ${m}${dictExt}]] == 0 } {
  641.         return 0
  642.     } else {
  643.         set result [elec::expandThis $cmd $matches]
  644.         set match [lindex  $result 0]
  645.         catch {set keystroke [lindex $result 1]}
  646.         if [string length $match] {
  647.             # we completed or cancelled, so move on
  648.             # WHY ISN'T THIS 'alreadyExpanding' ???????????? vmd
  649.             completion::already error
  650.             if { $match == 1 } {
  651.                 return 1
  652.             } else {
  653.                 set curPos [getPos]
  654.                 set retVal [completion [modeALike] Electric "${match}"]
  655. #                 alertnote [expr ($retVal != 0) ]
  656. #                 alertnote [info exists keystroke]
  657.                 if {([getPos] == $curPos) && [info exists keystroke]} {
  658.                     insertText $keystroke
  659.                 } 
  660.                 return $retVal
  661.             }
  662.         } else {
  663.             elec::alreadyExpanding Cmd
  664.             return 1
  665.         }
  666.     }
  667.     
  668. }
  669.  
  670.